package com.insight.export.generator;

import com.insight.common.enums.ExportFormat;
import com.insight.entity.DataSource;
import com.insight.entity.MetadataTable;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * T091: PDF格式数据字典生成器
 * <p>
 * 使用iText库生成PDF格式的数据字典文档.
 * 支持中文字体,包含表格、段落等丰富格式.
 * </p>
 *
 * <p><b>文档结构</b>:</p>
 * <ul>
 *   <li>标题: 数据字典</li>
 *   <li>数据源信息表</li>
 *   <li>表目录表</li>
 *   <li>各表详情(可选)</li>
 * </ul>
 *
 * @author Insight Team
 */
public class PdfExportGenerator implements ExportGenerator {

    private static final DateTimeFormatter TIMESTAMP_FORMAT =
            DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
    private static final DateTimeFormatter DISPLAY_FORMAT =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 字体和样式
    private Font titleFont;
    private Font headingFont;
    private Font normalFont;
    private Font tableHeaderFont;
    private Font tableDataFont;

    @Override
    public Path generate(DataSource dataSource, List<MetadataTable> tables, Path outputDir)
            throws IOException {
        // 参数验证
        validateParameters(dataSource, tables, outputDir);

        // 确保输出目录存在
        if (!Files.exists(outputDir)) {
            Files.createDirectories(outputDir);
        }

        // 生成文件名: datasource_timestamp.pdf
        String timestamp = LocalDateTime.now().format(TIMESTAMP_FORMAT);
        String fileName = String.format("%s_%s.pdf", sanitizeFileName(dataSource.getName()), timestamp);
        Path outputFile = outputDir.resolve(fileName);

        try {
            // 创建文档
            Document document = new Document(PageSize.A4);
            PdfWriter.getInstance(document, new FileOutputStream(outputFile.toFile()));

            // 初始化字体
            initializeFonts();

            // 打开文档
            document.open();

            // 添加内容
            addTitle(document, dataSource);
            addDataSourceInfo(document, dataSource);
            addTableOfContents(document, tables);
            addTableDetails(document, tables);
            addFooter(document);

            // 关闭文档
            document.close();

        } catch (DocumentException e) {
            throw new IOException("生成PDF文档失败: " + e.getMessage(), e);
        }

        return outputFile;
    }

    @Override
    public ExportFormat getSupportedFormat() {
        return ExportFormat.PDF;
    }

    @Override
    public String getFileExtension() {
        return "pdf";
    }

    /**
     * 验证参数
     */
    private void validateParameters(DataSource dataSource, List<MetadataTable> tables, Path outputDir) {
        if (dataSource == null) {
            throw new IllegalArgumentException("数据源不能为null");
        }
        if (tables == null) {
            throw new IllegalArgumentException("表列表不能为null");
        }
        if (outputDir == null) {
            throw new IllegalArgumentException("输出目录不能为null");
        }
    }

    /**
     * 初始化字体
     */
    private void initializeFonts() {
        try {
            // 尝试使用支持中文的字体
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

            titleFont = new Font(bfChinese, 18, Font.BOLD);
            headingFont = new Font(bfChinese, 14, Font.BOLD);
            normalFont = new Font(bfChinese, 10, Font.NORMAL);
            tableHeaderFont = new Font(bfChinese, 10, Font.BOLD);
            tableDataFont = new Font(bfChinese, 9, Font.NORMAL);
        } catch (Exception e) {
            // 降级到默认字体(支持基本拉丁字符)
            titleFont = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD);
            headingFont = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD);
            normalFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL);
            tableHeaderFont = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD);
            tableDataFont = new Font(Font.FontFamily.HELVETICA, 9, Font.NORMAL);
        }
    }

    /**
     * 添加标题
     */
    private void addTitle(Document document, DataSource dataSource) throws DocumentException {
        Paragraph title = new Paragraph("数据字典", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10);
        document.add(title);

        Paragraph subtitle = new Paragraph(
                "数据源: " + dataSource.getName() + " | 类型: " + dataSource.getDbType(),
                normalFont
        );
        subtitle.setAlignment(Element.ALIGN_CENTER);
        subtitle.setSpacingAfter(20);
        document.add(subtitle);
    }

    /**
     * 添加数据源信息
     */
    private void addDataSourceInfo(Document document, DataSource dataSource) throws DocumentException {
        // 章节标题
        Paragraph heading = new Paragraph("数据源信息", headingFont);
        heading.setSpacingBefore(10);
        heading.setSpacingAfter(10);
        document.add(heading);

        // 创建表格
        PdfPTable table = new PdfPTable(2);
        table.setWidthPercentage(100);
        table.setSpacingAfter(20);

        // 表头
        addTableHeaderCell(table, "项目");
        addTableHeaderCell(table, "值");

        // 数据行
        addTableDataRow(table, "数据源名称", dataSource.getName());
        addTableDataRow(table, "数据库类型", dataSource.getDbType().toString());
        addTableDataRow(table, "主机地址", dataSource.getHost() + ":" + dataSource.getPort());
        addTableDataRow(table, "数据库名",
                dataSource.getDatabaseName() != null ? dataSource.getDatabaseName() : "N/A");
        addTableDataRow(table, "用户名", dataSource.getUsername());

        document.add(table);
    }

    /**
     * 添加表目录
     */
    private void addTableOfContents(Document document, List<MetadataTable> tables) throws DocumentException {
        // 章节标题
        Paragraph heading = new Paragraph("表目录", headingFont);
        heading.setSpacingBefore(10);
        heading.setSpacingAfter(10);
        document.add(heading);

        if (tables.isEmpty()) {
            Paragraph empty = new Paragraph("暂无表信息", normalFont);
            empty.setSpacingAfter(20);
            document.add(empty);
            return;
        }

        // 创建表格
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setSpacingAfter(20);

        try {
            table.setWidths(new float[]{3, 4, 2, 2});
        } catch (DocumentException e) {
            // 使用默认宽度
        }

        // 表头
        addTableHeaderCell(table, "表名");
        addTableHeaderCell(table, "注释");
        addTableHeaderCell(table, "行数");
        addTableHeaderCell(table, "数据大小");

        // 数据行
        for (MetadataTable metaTable : tables) {
            addTableDataCell(table, metaTable.getTableName());
            addTableDataCell(table, metaTable.getTableComment() != null ? metaTable.getTableComment() : "");
            addTableDataCell(table, String.valueOf(metaTable.getRowCount() != null ? metaTable.getRowCount() : 0));
            addTableDataCell(table, formatBytes(0L /* getDataLength removed */));
        }

        document.add(table);
    }

    /**
     * 添加表详情
     */
    private void addTableDetails(Document document, List<MetadataTable> tables) throws DocumentException {
        if (tables.isEmpty()) {
            return;
        }

        // 章节标题
        Paragraph heading = new Paragraph("表详情", headingFont);
        heading.setSpacingBefore(10);
        heading.setSpacingAfter(10);
        document.add(heading);

        for (MetadataTable table : tables) {
            addTableDetail(document, table);
        }
    }

    /**
     * 添加单个表的详情
     */
    private void addTableDetail(Document document, MetadataTable table) throws DocumentException {
        // 表名标题
        Paragraph tableName = new Paragraph(
                table.getTableName() +
                        (table.getTableComment() != null ? " - " + table.getTableComment() : ""),
                headingFont
        );
        tableName.setSpacingBefore(10);
        tableName.setSpacingAfter(5);
        document.add(tableName);

        // 基本信息表格
        PdfPTable infoTable = new PdfPTable(2);
        infoTable.setWidthPercentage(100);
        infoTable.setSpacingAfter(15);

        addTableDataRow(infoTable, "模式",
                table.getTableSchema() != null ? table.getTableSchema() : "N/A");
        addTableDataRow(infoTable, "表类型",
                table.getTableType() != null ? table.getTableType() : "TABLE");
        addTableDataRow(infoTable, "行数",
                String.valueOf(table.getRowCount() != null ? table.getRowCount() : 0));
        addTableDataRow(infoTable, "数据大小", formatBytes(0L /* getDataLength removed */));
        addTableDataRow(infoTable, "索引大小", formatBytes(0L /* getIndexLength removed */));

        document.add(infoTable);
    }

    /**
     * 添加页脚
     */
    private void addFooter(Document document) throws DocumentException {
        Paragraph footer = new Paragraph(
                "生成时间: " + LocalDateTime.now().format(DISPLAY_FORMAT),
                normalFont
        );
        footer.setAlignment(Element.ALIGN_CENTER);
        footer.setSpacingBefore(20);
        document.add(footer);
    }

    /**
     * 添加表头单元格
     */
    private void addTableHeaderCell(PdfPTable table, String text) {
        PdfPCell cell = new PdfPCell(new Phrase(text, tableHeaderFont));
        cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setPadding(5);
        table.addCell(cell);
    }

    /**
     * 添加数据单元格
     */
    private void addTableDataCell(PdfPTable table, String text) {
        PdfPCell cell = new PdfPCell(new Phrase(text != null ? text : "", tableDataFont));
        cell.setPadding(5);
        table.addCell(cell);
    }

    /**
     * 添加数据行(键值对)
     */
    private void addTableDataRow(PdfPTable table, String key, String value) {
        addTableDataCell(table, key);
        addTableDataCell(table, value != null ? value : "");
    }

    /**
     * 格式化字节数为可读格式
     */
    private String formatBytes(Long bytes) {
        if (bytes == null || bytes == 0) {
            return "0 B";
        }
        if (bytes < 1024) {
            return bytes + " B";
        }
        if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        }
        if (bytes < 1024L * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024));
        }
        return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
    }

    /**
     * 清理文件名中的非法字符
     */
    private String sanitizeFileName(String fileName) {
        if (fileName == null) {
            return "export";
        }
        // 移除Windows文件名非法字符: < > : " / \ | ? *
        return fileName.replaceAll("[<>:\"/\\\\|?*]", "_");
    }
}
